package com.sdp.flow.controller;


import java.time.LocalDateTime;
import java.util.List;

import org.flowable.engine.ProcessEngine;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sdp.core.bizc.db.Query;
import com.sdp.core.bizc.vo.DataCenter;
import com.sdp.core.bizc.vo.Result;
import com.sdp.flow.db.entity.ActReProcdef;
import com.sdp.flow.db.entity.ActTemplateInfo;
import com.sdp.flow.db.service.IActReProcdefService;
import com.sdp.flow.db.service.IActTemplateInfoService;
import com.sdp.flow.utils.FlowConstants;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author qcy
 * @since 2021-06-30
 */
@RestController
@RequestMapping("/actReModel")
public class ActReModelController {

	@Autowired
	private Query query;
	
	@Autowired
	private IActTemplateInfoService templateInfoService;
	
	@Autowired
	private ProcessEngine processEngine;
	
	@Autowired
	private IActReProcdefService procdefService;
	
	@RequestMapping(value="/list")
	public Result<?> list(@RequestBody DataCenter dataCenter) {
		dataCenter.setSelectColumns(new String[]{"KEY_ID", "TEMPLATE_NAME", "TEMPLATE_CATEGORY",
		    "TEMPLATE_VERSION", "SYSTEM_NO", "DEPLOYMENT_ID", "CREATE_TIME", "TEMPLATE_DESCRIPTION"});
		IPage<ActTemplateInfo> pageList = query.page(templateInfoService, ActTemplateInfo.class, dataCenter);
		return Result.ok(pageList);
	}
	
	@RequestMapping(value="/queryById")
	public Result<?> queryModelById(@RequestParam String keyId)
	{
		if (!StringUtils.isEmpty(keyId)) {
			QueryWrapper<ActTemplateInfo> queryWrapper = new QueryWrapper<>();
			queryWrapper.lambda().eq(ActTemplateInfo::getKeyId, keyId);
			ActTemplateInfo model = templateInfoService.getOne(queryWrapper, false);
			if (model != null) {
				return Result.ok(model);
			} else {
				return Result.error("模板ID号对应的模板未找到!");
			}
			
		} else {
			return Result.error("模板ID号不能为空!");
		}
	}
	
	//保存模板
	@RequestMapping(value="/saveModel")
	public Result<?> saveModel(@RequestBody ActTemplateInfo templateInfo)
	{
		if (StringUtils.isEmpty(templateInfo.getKeyId())) {
			return Result.error("模板ID不能为空!");
		}
		//防止主键前台传入空格
		templateInfo.setKeyId(templateInfo.getKeyId().trim());
		QueryWrapper<ActTemplateInfo> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().eq(ActTemplateInfo::getKeyId, templateInfo.getKeyId());
		ActTemplateInfo oldRecord = templateInfoService.getOne(queryWrapper, false);
		if (oldRecord != null) {
			templateInfo.setUpdateTime(LocalDateTime.now());
			templateInfoService.updateById(templateInfo);
		} else {
			templateInfo.setCreateTime(LocalDateTime.now());
			if (templateInfo.getTemplateVersion() == null) {
				templateInfo.setTemplateVersion(FlowConstants.DEFAULT_VERSION);
			}
			templateInfoService.save(templateInfo);
		}
		return Result.ok("保存模板成功!");
	}
	
	@RequestMapping(value="/deployModel")
	public Result<?> deployModel(@RequestParam String keyId) {
		if (!StringUtils.isEmpty(keyId)) {
			//先删除部署的流程，再删除流程模板
			QueryWrapper<ActTemplateInfo> queryWrapper = new QueryWrapper<>();
			queryWrapper.lambda().eq(ActTemplateInfo::getKeyId, keyId);
			ActTemplateInfo model = templateInfoService.getOne(queryWrapper, false);
			if (model != null) {
				//先看看有没有部署过，部署过的先删除(这里的删除逻辑会 报错，不知道原因)
				if (!StringUtils.isEmpty(model.getDeploymentId())) {
//					RepositoryService repositoryService = processEngine.getRepositoryService();
//					repositoryService.deleteDeployment(model.getDeploymentId(), true);
				}

				//部署流程
				RepositoryService repositoryService = processEngine.getRepositoryService();
				

				Deployment deployment = repositoryService.createDeployment()
						.name(model.getTemplateName())
						.key(model.getKeyId())
						.category(model.getTemplateCategory())
						.addString(model.getTemplateName() + FlowConstants.FLOW_TEMPLATE_SUFFIX, model.getTemplateContent())
						.deploy();
				
				ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
						  .deploymentId(deployment.getId())
						  .singleResult();

				//更新流程定义信息，添加流程所属的业务系统(临时策略)
				UpdateWrapper<ActReProcdef> updateWrapper = new UpdateWrapper<>();
				updateWrapper.lambda().eq(ActReProcdef::getKey, keyId).set(ActReProcdef::getDescription, model.getSystemNo());
				procdefService.update(updateWrapper);		
				//更新模板表中的部署id
				model.setDeploymentId(deployment.getId());
				model.setProcDefId(processDefinition.getId());
				model.setDeploymentTime(LocalDateTime.now());
				templateInfoService.updateById(model);
			} else {
				return Result.error("模板ID号对应的模板不存在!");
			}
		} else {
			return Result.error("模板ID号不能为空!");
		}
		return Result.ok();
	}
	
	@RequestMapping(value="/clearModelHis")
	public Result<?> clearModelHis(@RequestParam String keyId) {
		if (!StringUtils.isEmpty(keyId)) {
			QueryWrapper<ActTemplateInfo> queryWrapper = new QueryWrapper<>();
			queryWrapper.lambda().eq(ActTemplateInfo::getKeyId, keyId);
			ActTemplateInfo model = templateInfoService.getOne(queryWrapper, false);
			if (model != null) {
				QueryWrapper<ActReProcdef> defQueryWrapper = new QueryWrapper<ActReProcdef>();
				defQueryWrapper.lambda().eq(ActReProcdef::getKey, keyId);
				List<ActReProcdef> defList = procdefService.list(defQueryWrapper);
				RepositoryService repositoryService = processEngine.getRepositoryService();
				for (ActReProcdef actReProcdef : defList) {
					//最新部署的不删除
					if (!actReProcdef.getDeploymentId().equals(model.getDeploymentId())) {
						repositoryService.deleteDeployment(actReProcdef.getDeploymentId(), true);
					}
				}
				return Result.ok();
			} else {
				return Result.error("模板ID号对应的模板不存在!");
			}
		} else {
			return Result.error("模板ID号不能为空!");
		}
	}
	
	@RequestMapping(value="/deleteModel")
	public Result<?> deleteModel(@RequestParam String keyId) {
		if (!StringUtils.isEmpty(keyId)) {
			//先删除部署的流程，再删除流程模板
			QueryWrapper<ActTemplateInfo> queryWrapper = new QueryWrapper<>();
			queryWrapper.lambda().eq(ActTemplateInfo::getKeyId, keyId);
			ActTemplateInfo model = templateInfoService.getOne(queryWrapper, false);
			if (model != null) {
				if (!StringUtils.isEmpty(model.getDeploymentId())) {
					RepositoryService repositoryService = processEngine.getRepositoryService();
					repositoryService.deleteDeployment(model.getDeploymentId(), true);
				}
				templateInfoService.removeById(keyId);
				return Result.ok();
			} else {
				return Result.error("模板ID号对应的模板不存在!");
			}
			
		} else {
			return Result.error("模板ID号不能为空!");
		}
	}
	
		
}
